package com.ctg.platform.core.security.entity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.userdetails.UserDetails;

public class Account implements UserDetails {
	
	private static final long serialVersionUID = 8026813053768023527L;

	private String id;
	
	private String username;
	
	private String password;
	
	private String disabled;
	
	private List<Role> roles;
	
	private Map<String, List<Resource>> roleResources;
	
	/**
	 * The default constructor
	 */
	public Account() {
		
	}
	/**
	 * 构造函数
	 * @param username 账户名
	 * @param disabled	是否启用 0:启用,1:冻结
	 */
	public Account(String username, String disabled) {
		if(StringUtils.isEmpty(username))
			throw new RuntimeException("username can not be empty");
		if(StringUtils.isEmpty(disabled)||(!disabled.equals("0") && !disabled.equals("1")))
			throw new RuntimeException("disabled must be \"0\" or \"1\"");
		this.username = username;
		this.disabled = disabled;
	}
	
	/**
	 * 构造函数
	 * @param username 账户名
	 */
	public Account(String username) {
		if(StringUtils.isEmpty(username))
			throw new RuntimeException("username can not be empty");
		this.username = username;
	}
	/**
	 * 构造函数
	 * @param username 账户名
	 * @param password 密码,未经过加密的
	 * @param disabled 是否启用 0:启用,1:冻结
	 */
	public Account(String username, String password, String disabled) {
		if(StringUtils.isEmpty(username))
			throw new RuntimeException("username can not be empty");
		if(StringUtils.isEmpty(disabled)||(!disabled.equals("0") && !disabled.equals("1")))
			throw new RuntimeException("disabled must be \"0\" or \"1\"");
		this.username = username;
		this.password = password;
		this.disabled = disabled;
	}

	public GrantedAuthority[] getAuthorities() {
		List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>(roles.size());
    	for(Role role : roles) {
    		grantedAuthorities.add(new GrantedAuthorityImpl(role.getName()));
    	}
        return grantedAuthorities.toArray(new GrantedAuthority[roles.size()]);
	}
	
	/**
	 * Returns the authorites string
	 * 
	 * eg. 
	 *    downpour --- ROLE_ADMIN,ROLE_USER
	 *    robbin --- ROLE_ADMIN
	 * 
	 * @return
	 */
	public String getAuthoritiesString() {
	    List<String> authorities = new ArrayList<String>();
	    for(GrantedAuthority authority : this.getAuthorities()) {
	        authorities.add(authority.getAuthority());
	    }
	    return StringUtils.join(authorities, ",");
	}

	/* (non-Javadoc)
	 * @see org.springframework.security.userdetails.UserDetails#getPassword()
	 */
	public String getPassword() {
		return password;
	}

	/* (non-Javadoc)
	 * @see org.springframework.security.userdetails.UserDetails#getUsername()
	 */
	public String getUsername() {
		return username;
	}

	/* (non-Javadoc)
	 * @see org.springframework.security.userdetails.UserDetails#isAccountNonExpired()
	 */
	public boolean isAccountNonExpired() {
		return true;
	}

	/* (non-Javadoc)
	 * @see org.springframework.security.userdetails.UserDetails#isAccountNonLocked()
	 */
	public boolean isAccountNonLocked() {
		return true;
	}

	/* (non-Javadoc)
	 * @see org.springframework.security.userdetails.UserDetails#isCredentialsNonExpired()
	 */
	public boolean isCredentialsNonExpired() {
		return true;
	}

	/* (non-Javadoc)
	 * @see org.springframework.security.userdetails.UserDetails#isEnabled()
	 */
	public boolean isEnabled() {
		return disabled.equals("0");
	}

	/**
	 * @return the id
	 */
	public String getId() {
		return id;
	}

	/**
	 * @return the disabled
	 */
	public boolean isDisabled() {
		return disabled.equals("1");
	}

	/**
	 * @return the roles
	 */
	public List<Role> getRoles() {
		return roles;
	}

	/**
	 * @return the roleResources
	 */
	public Map<String, List<Resource>> getRoleResources() {
		if(this.roleResources == null) {
			
			this.roleResources = new HashMap<String, List<Resource>>();
			
			for(Role role : this.roles) {
				String roleName = role.getName();
				Set<Resource> resources = role.getResources();
				for(Resource resource : resources) {
					String key = roleName + "_" + resource.getType();
					if(!this.roleResources.containsKey(key)) {
						this.roleResources.put(key, new ArrayList<Resource>());
					}
					this.roleResources.get(key).add(resource);					
				}
			}
			
		}
		return this.roleResources;
	}

	/**
	 * @param id the id to set
	 */
	public void setId(String id) {
		this.id = id;
	}

	/**
	 * @param password the password to set
	 */
	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * @param disabled the disabled to set
	 */
	public void setDisabled(String disabled) {
		this.disabled = disabled;
	}

	/**
	 * @param roles the roles to set
	 */
	public void setRoles(List<Role> roles) {
		this.roles = roles;
	}

	/**
	 * @return ��ȡdisabled
	 */
	public String getDisabled() {
		return disabled;
	}

	/**
	 * @param username ����username
	 */
	public void setUsername(String username) {
		this.username = username;
	}
	
}
